﻿Перем Консоль;
Перем Змея;
Перем Яблоко;

Перем ЗнакЛево;
Перем ЗнакВерх;

Функция КоординатаЯблокаЛево()
	Возврат ГСЧ(Консоль.Ширина, ЗнакЛево);
КонецФункции

Функция КоординатаЯблокаВерх()
	Возврат ГСЧ(Консоль.Высота, ЗнакВерх);
КонецФункции

Функция ГСЧ(Знач Макс, Знак)
	
	Медиана = Цел(Макс/2);
	
	Секунда = Секунда(ТекущаяДата());
	
	Результат = Медиана + (Секунда * Знак);
	
	Если Результат < 0 Тогда
		Результат = Результат * -1;
	КонецЕсли;
	Если Результат > Макс Тогда
		Результат = Результат - Макс;
	КонецЕсли;
	
	Знак = -Знак;
	
	Возврат Результат;
	
КонецФункции

Функция Сегмент()

	Сегмент = Новый Структура();
	Сегмент.Вставить("Направление", 0);
	Сегмент.Вставить("Лево", 0);
	Сегмент.Вставить("Верх", 0);
	
	Возврат Сегмент;
	
КонецФункции

Процедура НачальныеУстановки()

	Консоль = Новый Консоль();
	Консоль.ВидимостьКурсора(Ложь);
	Консоль.Очистить();
	
	ЗнакЛево = 1;
	ЗнакВерх = -1;
	
	СоздатьЗмею(10);
	
	Яблоко = Сегмент();
	Яблоко.Лево = 20;
	Яблоко.Верх = 12;
	НарисоватьСегмент(Яблоко, "О");
	
КонецПроцедуры

Процедура СоздатьЗмею(Знач Длина)

	Змея = Новый Массив;
	
	Пока Длина > 0 Цикл	
		Сегмент = Сегмент();
		Сегмент.Лево = Длина;
		Сегмент.Верх = 1;
		Сегмент.Направление = 3;	
		
		Змея.Добавить(Сегмент);
		
		Длина = Длина - 1;
	КонецЦикла;

КонецПроцедуры

Процедура НарисоватьЯблоко()

	НарисоватьСегмент(Яблоко, "О");

КонецПроцедуры

Функция ЕстьНовыйКадр();

	Направление = Змея[0].Направление;
	
	Если Консоль.НажатаКлавиша Тогда
		
		Клавиша = Консоль.Прочитать();
	
		Если Клавиша = 37 Тогда // лево
			Направление = 1;
		ИначеЕсли Клавиша = 38 Тогда // верх
			Направление = 2;
		ИначеЕсли Клавиша = 39 Тогда // право
			Направление = 3;
		ИначеЕсли Клавиша = 40 Тогда // вниз
			Направление = 4;
		ИначеЕсли Клавиша = 32 Тогда
			Возврат Ложь;
		КонецЕсли;
		
	КонецЕсли;
	
	УдалитьХвостЗмеи();
	ПередвинутьЗмею(Направление);
	СъестьЯблоко();
	НарисоватьГоловуЗмеи();
	НарисоватьЯблоко();
	
	Возврат Не ЕстьКоллизии();

КонецФункции

Процедура УдалитьХвостЗмеи()

	НарисоватьСегмент(Змея[Змея.Количество() - 1], " ");

КонецПроцедуры

Процедура НарисоватьГоловуЗмеи()
	НарисоватьСегмент(Змея[0], "K");
КонецПроцедуры

Процедура ПередвинутьЗмею(Знач Направление)
	
	Для Сч = 0 По Змея.Количество() - 1 Цикл
		
		СтароеНаправление = Змея[Сч].Направление;
		Змея[Сч].Направление = Направление;
		Направление = СтароеНаправление;
		СместитьСегмент(Змея[Сч]);
		
	КонецЦикла;
	
КонецПроцедуры

Процедура СъестьЯблоко()

	Если Змея[0].Лево = Яблоко.Лево и Змея[0].Верх = Яблоко.Верх Тогда
		
		Яблоко.Направление = Змея[0].Направление;
		НарисоватьСегмент(Яблоко, "К");
		СместитьСегмент(Яблоко);
		Змея.Вставить(0, Яблоко);
	
		Яблоко = Сегмент();
		Яблоко.Лево = КоординатаЯблокаЛево();
		Яблоко.Верх = КоординатаЯблокаВерх();
		
		ПроверитьГраницыСегмента(Яблоко, 2);
	
	КонецЕсли;

КонецПроцедуры

Процедура НарисоватьЗмею()
	Для Сч = 0 По Змея.Количество() - 1 Цикл
		НарисоватьСегмент(Змея[Сч], "К");
	КонецЦикла;
КонецПроцедуры

Функция ЕстьКоллизии()

	Верх = Змея[0].Верх;
	Лево = Змея[0].Лево;
	
	Для Сч = 1 По Змея.Количество() - 1 Цикл
		Если Змея[Сч].Лево = Лево и Змея[Сч].Верх = Верх Тогда
			Возврат Истина;
		КонецЕсли;
	КонецЦикла;

	Возврат Ложь;
	
КонецФункции

Процедура СместитьСегмент(Сегмент)
	
	Направление = Сегмент.Направление;
	
	Если Направление = 1 Тогда
		Сегмент.Лево = Сегмент.Лево - 1;
	ИначеЕсли Направление = 2 Тогда
		Сегмент.Верх = Сегмент.Верх - 1;
	ИначеЕсли Направление = 3 Тогда
		Сегмент.Лево = Сегмент.Лево + 1;
	ИначеЕсли Направление = 4 Тогда
		Сегмент.Верх = Сегмент.Верх + 1;
	КонецЕсли;
	
	ПроверитьГраницыСегмента(Сегмент);
	
КонецПроцедуры

Процедура ПроверитьГраницыСегмента(Сегмент, Поправка = 0)
	
	Если Сегмент.Лево >= Консоль.Ширина-Поправка Тогда
		Сегмент.Лево = 1;
	КонецЕсли;
	Если Сегмент.Лево < 1 Тогда
		Сегмент.Лево = Консоль.Ширина-Поправка;
	КонецЕсли;
	
	Если Сегмент.Верх >= Консоль.Высота-Поправка Тогда
		Сегмент.Верх = 1;
	КонецЕсли;
	Если Сегмент.Верх < 1 Тогда
		Сегмент.Верх = Консоль.Высота-Поправка;
	КонецЕсли;
КонецПроцедуры

Процедура НарисоватьСегмент(Знач Сегмент, Знач Симв)
	Консоль.КурсорЛево = Сегмент.Лево;
	Консоль.КурсорВерх = Сегмент.Верх;
	Консоль.Вывести(Симв);
КонецПроцедуры

Процедура Пуск()
	Консоль.Очистить();
	НарисоватьЗмею();
	Пока ЕстьНовыйКадр() Цикл
		Приостановить(100);
	КонецЦикла;
КонецПроцедуры

Процедура Заставка()
	
	НарисоватьКрасивуюРамку();
	
	Консоль.КурсорВерх = 6;
	Консоль.КурсорЛево = 15;
	Консоль.Вывести("Игра ""Змейка""");
	Консоль.КурсорВерх = 7;
	Консоль.КурсорЛево = 15;
	Консоль.Вывести("Играем стрелками. Выход - пробел.");
	Консоль.КурсорВерх = 8;
	Консоль.КурсорЛево = 15;
	Консоль.Вывести("Нажмите кнопку Any :)");
	
	Консоль.Прочитать();
	
КонецПроцедуры

Процедура НарисоватьКрасивуюРамку()

	Консоль.Очистить();
	Паттерн = "*****************************";
	Бортик = Паттерн;
	Ширина = 80;
	Пока СтрДлина(Бортик) < Ширина Цикл
		Бортик = Бортик + Паттерн;
	КонецЦикла;
	Бортик = Лев(Бортик, Ширина);
	
	Консоль.КурсорВерх = 0;
	Консоль.КурсорЛево = 0;
	Консоль.Вывести(Бортик);
	
	Для сч = 1 По Консоль.Высота-3 Цикл
		Консоль.КурсорЛево = 0;
		Консоль.КурсорВерх = Сч;
		Консоль.Вывести("*");
		Консоль.КурсорЛево = Консоль.Ширина;
		Консоль.Вывести("*");
	КонецЦикла;
	
	Консоль.Вывести(Бортик);

КонецПроцедуры

Процедура Выход()
	Консоль.Очистить();
	НарисоватьКрасивуюРамку();
	Консоль.КурсорВерх = 6;
	Консоль.КурсорЛево = 15;
	Консоль.Вывести("Гейм Овер");
	
	Пока Не Консоль.НажатаКлавиша Цикл
	КонецЦикла;
	Консоль.Прочитать();
	Консоль.Очистить();
	Консоль.ВидимостьКурсора(Истина);
КонецПроцедуры

НачальныеУстановки();
Заставка();
Пуск();
Выход();